package cn.cas.mango.dto.param;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


import java.math.BigDecimal;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Data
@NoArgsConstructor
@AllArgsConstructor

public class HotKeywords {
  Map<String, Double> map;


  private String keywordsName = "name";

  private String keywordsValue = "score";


  public Set<String> getKeywords() {
    return map.keySet();
  }

  public int size() {
    return map.size();
  }

  public Double get(String key) {
    if (map.containsKey(key)) {
      return map.get(key);
    }
    return null;
  }

  public void add(String key) {
    if (!map.containsKey(key)) {
      map.put(key, 0.01);
    }
  }

  public void addAll(HotKeywords keywords2) {
    for (String key: keywords2.getKeywords()) {
      map.put(key, keywords2.get(key));
    }
  }

  private void initialize() {
    map = new LinkedHashMap<>();
  }

  public double getNorm() {
    Collection<Double> r = map.values();
    Double sum = r.stream().map(x -> x * x).reduce((a, b) -> a + b).get();
    return Math.sqrt(sum);
  }

  private void addMap(Map<String, Object> map) {
    if (map == null || map.isEmpty()) return;
    String name = (String) map.get(keywordsName);
    double score;
    if (map.get(keywordsValue) instanceof BigDecimal) {
      score = ((BigDecimal) map.get(keywordsValue)).doubleValue();
    } else {
      score = (double)map.get(keywordsValue);
    }

    this.map.put(name, score);

  }

  private void construct(List<Map<String, Object>> data) {
    initialize();
    if (data == null || data.isEmpty()) {
      return;
    }
    for (Map<String, Object> map : data) {
      addMap(map);
    }
  }

  private void construct(Map<String, Object> data) {
    initialize();
    addMap(data);
  }

  public HotKeywords(Object data) {
    if (data == null) {
      construct(new LinkedHashMap<>());
    }
    if (data instanceof Map) {
      construct((Map) data);
    } else {
      construct((List) data);
    }
  }

}
